import { FIG_WX } from "./FIG_WX";
import { Cocos_Api_MG } from "./Cocos_Api_MG";
var app = getApp()

export class FIG_Ble {
    constructor() {
      FIG_WX.Get();
      FIG_Ble.instance = this;
    }
    /**
      *  Get 单例获取游戏摇杆
      * @return {FIG_Ble} 
      */
    static Get() {
        if (FIG_Ble.instance == undefined) {
            FIG_Ble.instance = new FIG_Ble();
        }
        return FIG_Ble.instance;
    }
    //-----------------蓝牙
    /**
     * 手动打开蓝牙列表并连接服务
     * @param {*} success 回调返回蓝牙名称列表["XX","XX2"]  
     */
    OpenCHooseLY(success = new Laya.Handler()) {
        let device = navigator.bluetooth.requestDevive({
            filters: [],
            optionalServices: []
        })
        console.log(device);
    }
    /**
     * 获取当前所有的蓝牙设备 名字+	RSSI
     */
    GetNowBlueAll(success_Hander, fail_Hander,must=false) {
        if (FIG_WX.instance.wx) {
            this.TfLanYaInit(() => {
                console.log("搜寻设备中...");
                FIG_WX.instance.wx.startBluetoothDevicesDiscovery({
                    //services: ['FEE7'],指定UUID
                    allowDuplicatesKey: false,
                    success(res) {
                        console.log(res)
                        setTimeout(() => {//添加延迟
                            FIG_WX.instance.wx.getBluetoothDevices({//获取列表所有蓝牙设备
                                success(res) {
                                    console.log(res);
                                    success_Hander(res.devices);
                                    FIG_WX.instance.wx.stopBluetoothDevicesDiscovery({
                                        success(res) {
                                            console.log("停止搜寻设备");
                                            app.globalData.searchFlag = true
                                        }
                                    })
                                },
                                fail(res) {
                                    FIG_WX.instance.wx.stopBluetoothDevicesDiscovery({
                                        success(res) {
                                            console.log("停止搜寻设备");
                                            app.globalData.searchFlag = true
                                        }
                                    })
                                    
                                    fail_Hander();
                                    console.log("获取蓝牙列表失败");
                                  
                                }
                            })
                        }, 1300)
                    },
                    fail(res) {
                        
                        fail_Hander();
                        console.log("获取蓝牙列表失败");

                    }

                })
            }, () => {
                fail_Hander();
            },must)
        } else {
            fail_Hander();
            console.log("当前页面暂不支持,请在微信端使用");
        }
    }
    /**
     * 通过蓝牙名字 来链接蓝牙设备  
     * @param {String} name 名字
     * @param {Laya.Handler} success_Hander 
     * @param {Laya.Handler} fail_Hander
     * @param {Laya.Handler} GameUpdate 数据更新回调
     *  @param {Laya.Handler} OverHander 断开回调
     */
    BlueTootByName(name, success_Hander, fail_Hander) {
        if (FIG_WX.instance.wx) {
            this.TfLanYaInit(() => {
                console.log("搜寻设备中...");
                FIG_WX.instance.wx.startBluetoothDevicesDiscovery({
                    //services: ['FEE7'],指定UUID
                    allowDuplicatesKey: false,
                    success(res) {
                        console.log(res)
                        setTimeout(() => {//添加延迟
                            FIG_WX.instance.wx.getBluetoothDevices({//获取列表所有蓝牙设备
                                success(res) {
                                    console.log(res);
                                    for (var i = 0; i < res.devices.length; i++) {
                                        if (res.devices[i].name == name) {//搜寻到此设备 链接 
                                            FIG_Ble.Ble_service.deviceId = res.devices[i].deviceId;
                                            FIG_WX.instance.wx.stopBluetoothDevicesDiscovery({
                                                success(res) {
                                                    console.log("停止搜寻设备");
                                            app.globalData.searchFlag = true
                                                }
                                            })

                                            FIG_Ble.instance.BlueTootBydeviceId(FIG_Ble.Ble_service.deviceId, success_Hander, fail_Hander);
                                            return;
                                        }
                                    }
                                    fail_Hander();
                                    console.log("暂未发现设备,请确保设备开启");
                                    FIG_WX.instance.wx.stopBluetoothDevicesDiscovery({
                                        success(res) {
                                            console.log("停止搜寻设备");
                                            app.globalData.searchFlag = true
                                        }
                                    })
                                },
                                fail(res) {
                                    FIG_WX.instance.wx.stopBluetoothDevicesDiscovery({
                                        success(res) {
                                            console.log("停止搜寻设备");
                                            app.globalData.searchFlag = true
                                        }
                                    })
                                    fail_Hander();
                                    console.log("链接失败请重试");
                                }
                            })
                        }, 1300)
                    },
                    fail(res) {
                        fail_Hander.run();
                        console.log("搜寻设备失败");

                    }

                })
            }, () => {
                fail_Hander();
            })
        } else {
            fail_Hander();
            console.log("当前页面暂不支持,请在微信端使用");
        }

    }
    TfLanYaInit(success_Hander, fail_Hander, must = false) {
        //!this.InitLanY  每次获取都重启蓝牙
        if (!this.InitLanY || must) {
            console.log("蓝牙初始化中...");
            FIG_WX.instance.wx.closeBluetoothAdapter(
                {
                    success(res) {
                        console.log("成功关闭蓝牙模块");
                        FIG_WX.instance.wx.openBluetoothAdapter(
                            {
                                success(res) {
                                    console.log("成功初始化蓝牙适配器");
                                    FIG_Ble.instance.InitLanY = true;
                                    success_Hander();
                                },
                                fail(res) {
                                    console.log(res);
                                    fail_Hander();
                                    console.log("请手动开启蓝牙");
                                    app.globalData.BELFlag = true
                                }
                            }
                        )
                    },
                    fail(res) {
                        console.log("蓝牙关闭失败");
                        console.log("请手动关闭蓝牙");
                        fail_Hander();
                    }
                }
            )
        } else {
            success_Hander();
        }

    }

    /**初始化蓝牙 结束回调===>  多次注册无效 重新注册会覆盖回调只保留当前 需要同时多个回调请修改GameFIG*/
    InitBlueOverHander(OverHander) {
        if (!FIG_WX.instance.wx) {
            return
        }
        FIG_WX.instance.wx.offBLEConnectionStateChange();
        FIG_WX.instance.wx.onBLEConnectionStateChange((res) => {//断开后二次监听
            if (!res.connected) {
                console.log("已断开蓝牙");
                FIG_WX.instance.TiShiKuang("蓝牙已断开");//之后搞个重连
                OverHander.runWith(res.deviceId);//断开监听
            }
        })
    }

    /**
     * 初始化蓝牙 更新回调===>  多次注册无效 重新注册会覆盖回调只保留当前 需要同时多个回调请调用AddBlueChangeHander
     * @param {*} GameUpdate 
     */
    InitBlueChangeHander(GameUpdate) {
        if (!FIG_WX.instance.wx) {
            return
        }
        FIG_WX.instance.wx.offBLECharacteristicValueChange();
        FIG_WX.instance.wx.onBLECharacteristicValueChange((res) => {
            GameUpdate.runWith(res);
        })
    }

    /**
     * 添加蓝牙 更新回调 多次调用可以同时监听多个回调  
     * @param {*} Fun 回调方法fun 参数res.value是值 res.deviceId是对应的节点
     */
    AddBlueChangeHander(Fun) {
        if (!FIG_WX.instance.wx) {
            return
        }
        FIG_WX.instance.wx.onBLECharacteristicValueChange(Fun)
    }
    /**
         * 删除蓝牙 更新回调    暂时全部移除 微信小程序有问题不能单独移除
         * @param {*} Fun 回调方法fun
         */
    DeletBlueChangeHander(Fun) {
        if (!FIG_WX.instance.wx) {
            return
        }
        FIG_WX.instance.wx.offBLECharacteristicValueChange()
    }

    /**
    * 添加蓝牙 断开回调 多次调用可以同时监听多个回调  
    * @param {*} Fun 回调方法fun 参数res.value是值 res.deviceId是对应的节点
    */
    AddBlueOverHander(Fun) {
        if (!FIG_WX.instance.wx) {
            return
        }
        FIG_WX.instance.wx.onBLEConnectionStateChange(Fun)
    }
    /**
         * 删除蓝牙 断开回调   暂时全部移除 微信小程序有问题不能单独移除
         * @param {*} Fun 回调方法fun
         */
    DeletBlueOverHander(Fun) {
        if (!FIG_WX.instance.wx) {
            return
        }
        FIG_WX.instance.wx.offBLEConnectionStateChange()
    }

    /**
     * 通过蓝牙ID 来链接蓝牙设备  
     * @param {String} deviceId ID
     * @param {Laya.Handler} success_Hander 
     * @param {Laya.Handler} fail_Hander 
     * @param {Laya.Handler} GameUpdate 数据更新回调
     * @param {Laya.Handler} OverHander 断开回调
     */


    BlueTootBydeviceId(device, success_Hander, fail_Hander) {
        if (FIG_WX.instance.wx) {
            this.writeIndex = 0;
            console.log("连接设备中...");
            FIG_WX.instance.wx.createBLEConnection({
                connectionPriority: "high",
                deviceId: device.deviceId,
                success(res) {
                    console.log(device,"连接成功");
                    var app = getApp()
                    app.globalData.connects.push(device.name)
                    FIG_Ble.Ble_service.deviceId = device.deviceId;
                    FIG_Ble.Ble_OTA.deviceId = device.deviceId;
                    FIG_Ble.instance.GetServices(FIG_Ble.Ble_OTA, () => {
                        FIG_Ble.instance.GetServices(FIG_Ble.Ble_service, success_Hander, fail_Hander);
                    }, fail_Hander);
                },
                fail(res) {
                    console.log("连接失败", res)
                    fail_Hander();
                    console.log("连接失败,请重试");
                }
            })
        } else {
            fail_Hander();
            console.log("当前页面暂不支持,请在微信端使用");
        }
    }

    GetServices(Out_service, success_Hander, fail_Hander) {
        if (FIG_WX.instance.wx) {
            FIG_WX.instance.wx.getBLEDeviceServices({//获取所有服务
                deviceId: Out_service.deviceId,
                success(res) {
                    var All_UUID = res.services;
                    console.log("所有服务:", All_UUID)
                    for (var a = 0; a < All_UUID.length; a++) {
                        var EgcID = All_UUID[a].uuid;//取出UUID
                        var UID_slice = EgcID.slice(4, 8);//截取4-8位
                        if (UID_slice == Out_service.ServiceBle) {//180A 0001
                            Out_service.serviceId = EgcID;
                            FIG_Ble.instance.Characteristics(Out_service, success_Hander, fail_Hander);
                            return;
                        }
                    }
                },
                fail() {
                    fail_Hander();
                    console.log("获取设备服务失败");
                }
            })
        }
    }
    /**获取特征值 */
    Characteristics(Out_service, success_Hander, fail_Hander) {
        if (FIG_WX.instance.wx) {
            FIG_WX.instance.wx.getBLEDeviceCharacteristics({
                deviceId: Out_service.deviceId,
                serviceId: Out_service.serviceId,
                success(res) {
                    var ctcs = res.characteristics;
                    var ctcs_len = res.characteristics.length;

                    for (var a = 0; a < ctcs_len; a++) {
                        var UUID = ctcs[a].uuid;
                        var slice = UUID.slice(4, 8);
                        if (slice == Out_service.Cha_w) {//0003
                            console.log("特征值W" + UUID);
                            Out_service.characteristicId_w = UUID;
                        } else if (slice == Out_service.Cha_r) {
                            console.log("特征值R" + UUID);
                            Out_service.characteristicId_R = UUID;
                        }
                    }

                    success_Hander({ "deviceId": Out_service.deviceId, "serviceId": Out_service.serviceId, characteristicId_w: Out_service.characteristicId_w, characteristicId_R: Out_service.characteristicId_R });
                },
                fail(res) {

                    console.log(res);
                    fail_Hander();
                    console.log("获取设备特征值失败!");
                }
            })
        } else {
            fail_Hander();
            console.log("当前页面暂不支持,请在微信端使用");
        }

    }

    /**
     * 开启 关闭当前连接 notify监听 
     * @param {*} Data_ID 数据
     * @param {*} ttff 开启/关闭
     */
    notifyBLE(Data_ID, ttff = false) {
        if (FIG_WX.instance.wx) {
            FIG_WX.instance.wx.notifyBLECharacteristicValueChange({
                state: ttff, // 启用 notify 功能
                // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
                deviceId: Data_ID.deviceId,
                // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
                serviceId: Data_ID.serviceId,
                // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
                characteristicId: Data_ID.characteristicId_R,
                success(res) {

                    console.log((ttff ? "开启" : "关闭") + "Notify监听")
                }
            })
        }

    }

    /**
     * 当前连接的蓝牙发送指令
     * @param {String|Uint8Array} msg  字符串或者unit8array
     * @param {Laya.Handler} success_Hander 
     * @param {Laya.Handler} fail_Hander
     * @param {*} Data_ID 节点数据
     */

    BlueSendTap(msg, success_Hander = new Laya.Handler(), fail_Hander = new Laya.Handler(), Data_ID) {

        if (FIG_WX.instance.wx) {
            if (typeof (msg) == "string") {
                var buffer = Cocos_Api_MG.StrToArrayBuffer(msg).buffer;
            } else {
                var buffer = msg.buffer;
            }

            FIG_WX.instance.wx.writeBLECharacteristicValue({
                deviceId: Data_ID.deviceId,
                serviceId: Data_ID.serviceId,
                characteristicId: Data_ID.characteristicId_w,
                value: buffer,
                //   writeType:"write",
                success(res) {
                    success_Hander && success_Hander.run();
                    fail_Hander && fail_Hander.clear();
                    //   FIG_Ble.instance.BlueReadTap(Data_ID, res);
                },
                fail(res) {
                    FIG_Ble.instance.writeIndex += 1;
                    console.log(FIG_Ble.instance.writeIndex);
                    if (FIG_Ble.instance.writeIndex < 3) {
                        console.log("第" + FIG_Ble.instance.writeIndex + "次发送失败*", res);
                        FIG_Ble.instance.BlueSendTap(msg, success_Hander, fail_Hander, Data_ID);
                    } else {
                        FIG_Ble.instance.writeIndex = 0;
                        fail_Hander && fail_Hander.run();
                        success_Hander && success_Hander.clear();
                        console.log("第3次发送失败", res);
                    }

                }
            })
        } else {
            fail_Hander && fail_Hander.run();

        }
    }

    /**
     * 当前连接的设备返回指令 
     */
    BlueReadTap(Data_ID) {
        if (FIG_WX.instance.wx) {
            FIG_WX.instance.wx.readBLECharacteristicValue({
                // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
                deviceId: Data_ID.deviceId,
                // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
                serviceId: Data_ID.serviceId,
                // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
                characteristicId: Data_ID.characteristicId_R,
                success(res) {
                    console.log("数据读取成功", res)
                },
                fail(res) {
                    console.log("数据读取失败", res)
                }
            })
        } else {
            fail_Hander.run();

        }
    }

    /**断开当前蓝牙设备 */
    BlueOut(Data_ID) {
        if (FIG_WX.instance.wx && Data_ID) {
            FIG_WX.instance.wx.closeBLEConnection({
                deviceId: Data_ID,
                success() {
                    console.log("成功断开设备链接");
                }
            })
        }
    }
    /**
        * 打印到外部 
        * @param {*} FunToLog 打印方法
        */
    InitLog(FunToLog) {
        this.FunToLog = FunToLog;
    }
    /**
     * 打印
     * @param {*} msg 
     */
    log(msg) {
        if (this.FunToLog) {
            this.FunToLog(msg)
        } else {
            console.log(msg);
        }
    }
    //--------------

    /**
   * 帧执行OTA 命令 自动加帧
   * @param {*} cmd 命令 
   * @param {*} success_Hander 成功回调
   * @param {*} fail_Hander 失败回调
   */
    OTACmdApp(cmd, success_Hander, fail_Hander, tfadd = false) {
        if (!tfadd) {
            cmd.Frame_seq = FIG_Ble.OTACMDs.Frame_seq;
        }
        var data = cmd.ToByte();
        cmd.success_Hander = success_Hander;
        cmd.fail_Hander = fail_Hander;
        this.log("APP=> " + data);
        this.BlueSendTap(data, Laya.Handler.create(this, () => {
            this.log("APP=>" + cmd.name + " =>成功");
            if (!tfadd) {
                FIG_Ble.OTACMDs.Frame_seq++;
            }

        }), Laya.Handler.create(this, () => {
            this.log("APP=> " + cmd.name + " =>失败");
            fail_Hander.run();
        }), FIG_Ble.Ble_OTA);
    }


    /**
       * OTA升级服务
       * @param {ArrayBuffer} BinData 升级数据 
       * @param {*} success_Hander 成功回调
       * @param {*} fail_Hander 失败回调
       * @param {*} Loading_Hander 进度回调 0-1的值
       */
    OTAToUp(deviceId, BinData = new ArrayBuffer(), success_Hander, fail_Hander, Loading_Hander) {
        FIG_Ble.OTACMDs.remove();
        FIG_Ble.Ble_OTA.deviceId = deviceId;
        //bk3266 OTA 格式   不同格式对应不同数据 本产品暂只使用3266  其他参考文
        var BinDatas = new Uint8Array(BinData);
        var Header = Cocos_Api_MG.ArrayBufferToStr(BinData.slice(0, 32)).split(" ");//32byte
        this.AddBlueChangeHander(this.OTAUpdate.bind(this));
        this.notifyBLE(FIG_Ble.Ble_OTA, true);
        //先查询设备信息
        this.OTACmdApp(FIG_Ble.OTACMDs.QueryD, Laya.Handler.create(this, () => {
            //发送升级请求
            FIG_Ble.OTACMDs.SendUp.Payload = Header
            this.OTACmdApp(FIG_Ble.OTACMDs.SendUp, Laya.Handler.create(this, () => {
                console.log("开始升级")
                //FIG_Ble.OTACMDs.Frame_seq = 0;
                FIG_Ble.OTACMDs.IssUp.success_Hander = success_Hander;
                FIG_Ble.OTACMDs.IssUp.fail_Hander = fail_Hander;
                // this.OTASendBin(FIG_Ble.OTACMDs.IssUp, BinData, success_Hander, fail_Hander, Loading_Hander);
                Laya.timer.loop(100, this, this.OTASendBin, [FIG_Ble.OTACMDs.IssUp, BinDatas, success_Hander, fail_Hander, Loading_Hander]);//这里控制发送速度
            }), fail_Hander);
        }), fail_Hander);
    }
    OTASendBin(cmd, BinDatas = new Uint8Array(), success_Hander, fail_Hander, Loading_Hander) {
        if (this.SendErr) {
            Laya.timer.clear(this, this.OTASendBin);
            return
        };
        if (FIG_Ble.OTACMDs.addr >= FIG_Ble.OTACMDs.AllLen - 1) {
            //发送请求
            Laya.timer.clear(this, this.OTASendBin);
            this.OTACmdApp(FIG_Ble.OTACMDs.NotDisResults, Laya.Handler.create(this, () => {
            }), fail_Hander);
        } else {
            var len = FIG_Ble.OTACMDs.size + 4;
            if ((FIG_Ble.OTACMDs.AllLen - FIG_Ble.OTACMDs.addr) < FIG_Ble.OTACMDs.size) {
                len = (FIG_Ble.OTACMDs.AllLen - FIG_Ble.OTACMDs.addr) + 4;
            }
            cmd.Length = Cocos_Api_MG.HexNumberToString(len, 4);
            var JD = FIG_Ble.OTACMDs.addr / (BinDatas.byteLength - 32);
            Loading_Hander.runWith([JD, len]);

            //uint发送
            // var SendData = BinDatas.slice(FIG_Ble.OTACMDs.addr, FIG_Ble.OTACMDs.addr + FIG_Ble.OTACMDs.size);
            // var otaBlockData = new Uint8Array(8);
            // otaBlockData[0] = 0x05;
            // otaBlockData[1] = parseInt("0x" + FIG_Ble.OTACMDs.Frame_seq);
            // otaBlockData[2] = Cocos_Api_MG.loUint16(len);
            // otaBlockData[3] = Cocos_Api_MG.hiUint16(len);
            // otaBlockData[4] = Cocos_Api_MG.Uint32_Lo1(FIG_Ble.OTACMDs.addr);
            // otaBlockData[5] = Cocos_Api_MG.Uint32_Lo2(FIG_Ble.OTACMDs.addr);
            // otaBlockData[6] = Cocos_Api_MG.Uint32_Lo3(FIG_Ble.OTACMDs.addr);
            // otaBlockData[7] = Cocos_Api_MG.Uint32_Lo4(FIG_Ble.OTACMDs.addr);

            // var OutData = new Uint8Array(otaBlockData.length + SendData.length);//合并
            // OutData.set(otaBlockData, 0);
            // OutData.set(SendData, otaBlockData.length);

            //--字符串发送
            var data = BinDatas.slice(FIG_Ble.OTACMDs.addr, FIG_Ble.OTACMDs.addr + FIG_Ble.OTACMDs.size);
            var str = "05" + Cocos_Api_MG.HexNumberToString(FIG_Ble.OTACMDs.Frame_seq, 2) + Cocos_Api_MG.HexNumberToString2(len, 4) + Cocos_Api_MG.HexNumberToString2(FIG_Ble.OTACMDs.addr, 8) + Cocos_Api_MG.ArrayBufferToStr2(data);

            this.BlueSendTap(str, Laya.Handler.create(this, () => {


            }), Laya.Handler.create(this, () => {
                Laya.timer.clear(this, this.OTASendBin);
                this.log("APP=>" + cmd.name + "=>失败");
                fail_Hander.run();
            }), FIG_Ble.Ble_OTA);
            FIG_Ble.OTACMDs.addr += FIG_Ble.OTACMDs.size;//下一个开始地址
            FIG_Ble.OTACMDs.Frame_seq++;

        }

    }

    //错误码 集合
    //001 帧不同步
    //002 设备不响应升级
    OTAUpdate(res) {
        var datas = new Uint8Array(res.value);
        var txt = Cocos_Api_MG.ArrayBufferToStr(res.value);
        var arr = txt.split(" ");
        var cmd = FIG_Ble.DeviceCMD[arr[0]];
        //  this.log("Device=> " + txt);
        var Frame_seq = parseInt(arr[1], 16);
        if (cmd) {
            switch (arr[0]) {
                case "02": {
                    this.log("Device=>" + txt);
                    if (Frame_seq == FIG_Ble.OTACMDs.QueryD.Frame_seq) {
                        cmd.Payload = arr.slice(3, 10);
                        FIG_Ble.OTACMDs.QueryD.fail_Hander = null;
                        FIG_Ble.OTACMDs.QueryD.success_Hander.run();
                        this.log("Device=> " + cmd.name + " =>成功");
                    } else {
                        console.log(Frame_seq)
                        this.log("Device=> Error001 =>" + cmd.name);
                        FIG_Ble.OTACMDs.QueryD.success_Hander = null;
                        FIG_Ble.OTACMDs.QueryD.fail_Hander.run();
                    }
                    break;
                } case "04": {
                    this.log("Device=>" + txt);
                    if (Frame_seq == FIG_Ble.OTACMDs.SendUp.Frame_seq) {//文档有错 ！！！！
                        cmd.Payload = arr.slice(4, 15);
                        var result = cmd.Payload[0];
                        var size = Cocos_Api_MG.buildUint16(datas[14], datas[13]);
                        if (size > FIG_Ble.OTACMDs.SizeMax) {
                            FIG_Ble.OTACMDs.size = FIG_Ble.OTACMDs.SizeMax;
                        } else {
                            FIG_Ble.OTACMDs.size = size;
                        }

                        FIG_Ble.OTACMDs.addr = parseInt(arr[8] + arr[7] + arr[6] + arr[5], 16);//  Cocos_Api_MG.buildUint32(datas[8], datas[7], datas[6], datas[5]);
                        FIG_Ble.OTACMDs.AllLen = parseInt(arr[12] + arr[11] + arr[10] + arr[9], 16); Cocos_Api_MG.buildUint32(datas[12], datas[11], datas[10], datas[9]) + FIG_Ble.OTACMDs.addr;
                        if (result == "00") {
                            this.log("Device=>" + cmd.name + "=>size<=" + size);
                            this.log("Device=>" + cmd.name + "=>addr<=" + FIG_Ble.OTACMDs.addr);
                            this.log("Device=>" + cmd.name + "=>数据总大小<=" + FIG_Ble.OTACMDs.AllLen / 1024 + "kb");

                            FIG_Ble.OTACMDs.SendUp.fail_Hander = null;
                            FIG_Ble.OTACMDs.SendUp.success_Hander.run();
                        } else {
                            this.log("Device=> Error002 =>" + cmd.name);
                            FIG_Ble.OTACMDs.SendUp.success_Hander = null;
                            FIG_Ble.OTACMDs.SendUp.fail_Hander.run();
                        }
                    } else {
                        this.log("Device=> Error001 =>" + cmd.name);
                        FIG_Ble.OTACMDs.SendUp.success_Hander = null;
                        FIG_Ble.OTACMDs.SendUp.fail_Hander.run();
                    }
                    break;
                } case "06": {
                    var addr = Cocos_Api_MG.buildUint32(datas[7], datas[6], datas[5], datas[4]);
                    if ((Frame_seq != this.mLastFrameSeq && addr != this.mLastAddress)) {
                        FIG_Ble.OTACMDs.Frame_seq = Frame_seq + 1; //测试关闭掉 否则无限重发
                        FIG_Ble.OTACMDs.addr = addr;
                        this.mLastFrameSeq = Frame_seq;
                        this.mLastAddress = addr;
                        this.log("Device=>" + cmd.name + "=> 帧:" + Frame_seq);
                        this.log("Device=>" + cmd.name + "=> 地址:" + FIG_Ble.OTACMDs.addr);
                    } else {
                        this.SendErr = true;
                        FIG_Ble.OTACMDs.IssUp.success_Hander = null;
                        FIG_Ble.OTACMDs.IssUp.fail_Hander.run();
                    }

                    break;
                } case "08": {
                    var result = arr[4];
                    this.log("Device=>" + txt);
                    if (result == "00") {//08 47 01
                        this.log("Device=>" + cmd.name + "=>升级成功");
                        FIG_Ble.OTACMDs.IssUp.fail_Hander = null;
                        FIG_Ble.OTACMDs.IssUp.success_Hander.run();
                        this.OTACmdApp(FIG_Ble.OTACMDs.NotResD, Laya.Handler.create(this, () => {
                            this.log("Device=> 设备重启成功 =>");
                        }), Laya.Handler.create(this, () => {
                            this.log("Device=> 设备重启失败 请手动重启设备 =>");
                        }));
                    } else {
                        this.log("Device=> 升级失败 =>");
                        FIG_Ble.OTACMDs.IssUp.success_Hander = null;
                        FIG_Ble.OTACMDs.IssUp.fail_Hander.run();
                        this.OTACmdApp(FIG_Ble.OTACMDs.NotResD, Laya.Handler.create(this, () => {
                            this.log("Device=> 设备重启成功 =>");
                        }), Laya.Handler.create(this, () => {
                            this.log("Device=> 设备重启失败 请手动重启设备 =>");
                        }));
                    }
                    break;
                } case "09": {
                    var size = Cocos_Api_MG.buildUint16(datas[5], datas[4]);
                    if (size > FIG_Ble.OTACMDs.SizeMax) {
                        FIG_Ble.OTACMDs.size = FIG_Ble.OTACMDs.SizeMax;
                    } else {
                        FIG_Ble.OTACMDs.size = size;
                    }
                    this.log("Device=> 更新速率 =>" + FIG_Ble.OTACMDs.size);
                    FIG_Ble.OTACMDs.ResSize.Frame_seq = Frame_seq;
                    this.OTACmdApp(FIG_Ble.OTACMDs.ResSize, Laya.Handler.create(this, () => {
                        this.log("App:更新速率成功");
                    }), Laya.Handler.create(this, () => {
                        this.log("App:更新速率失败");
                    }), true);
                    break;
                }

            }

        } else {
            this.log("OTA接收数据:" + "未知 " + txt);
        }

    }

}
class Ble_serviceId {
    constructor(ServiceBle, Cha_w, Cha_r, name) {
        this.name = name;
        this.deviceId = "";//设备id 注意这个是最新连接设备的设备ID  
        this.serviceId = "";//服务id
        this.characteristicId_w = "";//写入特征值
        this.characteristicId_R = "";//读取特征值

        this.ServiceBle = ServiceBle;//与设备交互的服务后缀
        this.Cha_w = Cha_w;//与设备交互的服务 写入 特征值后缀
        this.Cha_r = Cha_r;//与设备交互的服务 读取 特征值后缀

    }

}
class CMD_OTA {
    constructor(name, CMD, Length, Payload = []) {
        this.name = name;
        this.CMD = CMD;
        this.Length = Length;
        this.Payload = Payload;
        this.Frame_seq = 0;
        this.success_Hander = null;
        this.fail_Hander = null;
    }
    ToByte() {
        var Payload = "";
        for (var a = 0; a < this.Payload.length; a++) {
            Payload += this.Payload[a];
        }
        var str = this.CMD + Cocos_Api_MG.HexNumberToString(this.Frame_seq, 2) + this.Length + "00" + Payload;
        return str;
    }
}

export class Ble_Tools {
    constructor() {

    }


    // //获取到旋转的正确数值
    // GetInspectorRotationValueMethod(transform) {
    //     // 获取原生值
    //     System.Type transformType = transform.GetType();
    //       PropertyInfo m_propertyInfo_rotationOrder = transformType.GetProperty("rotationOrder", BindingFlags.Instance | BindingFlags.NonPublic);
    //       object m_OldRotationOrder = m_propertyInfo_rotationOrder.GetValue(transform, null);
    //       MethodInfo m_methodInfo_GetLocalEulerAngles = transformType.GetMethod("GetLocalEulerAngles", BindingFlags.Instance | BindingFlags.NonPublic);
    //       object value = m_methodInfo_GetLocalEulerAngles.Invoke(transform, new object[] { m_OldRotationOrder });
    //       string temp = value.ToString();
    //     //将字符串第一个和最后一个去掉
    //     temp = temp.Remove(0, 1);
    //     temp = temp.Remove(temp.Length - 1, 1);
    //     //用‘，’号分割
    //     string[] tempVector3;
    //     tempVector3 = temp.Split(',');
    //       //将分割好的数据传给Vector3
    //       Vector3 vector3 = new Vector3(float.Parse(tempVector3[0]), float.Parse(tempVector3[1]), float.Parse(tempVector3[2]));
    //     return vector3;
    // }
}
/**命令集 */
Ble_Tools.commands = {
    /**单独获取四元数 限制120帧/s*/
    OnlyQuaternion: "AB010F000030",
    /**获取全部数据 无限制 */
    AllDate: "AB01FFFFFF",
    /**获取版本号 */
    GetDL: "AB08",
    /**获取电量 */
    GetDL: "AB09",
    /**寻找设备 闪三下*/
    SanSan: "AB0B",
    /**关闭按键关机功能 */
    OpenKai: "ABFC01",
    /**开启按键关机功能 */
    CloseKai: "ABFC00",
}
/**交互 服务 */
FIG_Ble.Ble_service = new Ble_serviceId("0001", "0002", "0003", "交互服务");
/**升级 服务 */
FIG_Ble.Ble_OTA = new Ble_serviceId("FFC0", "FFC1", "FFC2", "升级服务");
/**OTA的App CMD命令集 */
FIG_Ble.OTACMDs = {
    QueryD: new CMD_OTA("查询设备", "01", "00"),//查询设备 APP->Device
    SendUp: new CMD_OTA("发送升级请求", "03", "20"),//发送升级请求 APP->Device
    IssUp: new CMD_OTA("下发升级数据包", "05"),//下发升级数据包 APP->Device
    NotDisResults: new CMD_OTA("通知数据下发结束并检查结果", "07", "00"),//通知数据下发结束并检查结果 APP->Device
    ResSize: new CMD_OTA("响应更新size", "0A", "00"),// APP 响应更新 size APP->Device
    NotResD: new CMD_OTA("通知重启设备", "0B", "00"),// APP 通知重启设备  APP->Device
    Frame_seq: 0,//当前帧
    addr: 0,//当前地址
    addr2: 0,//当前地址
    size: 0,//当前帧大小
    AllLen: 0,//升级数据总长度
    SizeMax: 16,//最大速度
    remove: () => {
        FIG_Ble.OTACMDs.Frame_seq = 0;//当前帧
        FIG_Ble.OTACMDs.addr = 0;//当前地址
        FIG_Ble.OTACMDs.addr2 = 0;//当前地址
        FIG_Ble.OTACMDs.size = 0;//当前帧大小

    }
}
/**OTA的Device CMD命令集 */
FIG_Ble.DeviceCMD = {
    "02": new CMD_OTA("上报设备", "02", "07"),//上报设备 Device->APP
    "04": new CMD_OTA("响应升级", "04", "0B"),//响应升级 Device->APP
    "06": new CMD_OTA("请求数据包重传", "06", "04"),//请求数据包重传 Device->APP
    "08": new CMD_OTA("上报升级检查结果", "08", "01"),//上报升级检查结果 Device->APP
    "09": new CMD_OTA("请求更新size", "09", "02"),//请求更新 size Device->APP
}

